package com.my.screenadapter.myHandler;

import android.app.Activity;
import android.app.Fragment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.lang.ref.WeakReference;

/**
 * Created by ${张英杰} on 2017/10/13.
 * <p>
 * Handler的内存泄露问题：
 * 目的：当一个handler延时10分钟执行完毕，但是没执行完毕当前的Activity被finish(),handler执行时需要当前的界面，界面执行了finish但是后台依然在
 * 运行，实际没有关闭，这会导致内存泄露。
 * <p>
 * 1.定义一个内部类时，会默认拥有外部类对象引用，所以建议使用内部类 时，最好定义为一个静态内部类
 * 2.引用的强弱： 强引用--软引用--弱引用
 * 普通new叫强引用，内存不足不会自动回收，销毁或制空才会被回收
 * 软引用：一个对象引用到另一个对象（如果内存不足会回收这个对象）
 * 弱引用：  如果不存在  访问不到
 */

public abstract class WeakHandler<T> extends Handler {

    private WeakReference<T> weakReference;

    //构造私有化,让调用者必须传递一个Activity 或者 Fragment的实例
    public WeakHandler() {
    }

//    public WeakHandler(Context context) {
//        this.weakReference = new WeakReference(context);
//    }
    //创建主线程Handler使用的构造器
    public WeakHandler(T weakReference) {
        this.weakReference = new WeakReference<>(weakReference);
    }

    private static final String TAG = "WeakHandler===";

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        // 通过  软引用  看能否得到activity示例
        // 防止内存泄露
        if (weakReference != null && weakReference.get() != null) {
            Object obj = weakReference.get();
            T t = weakReference.get();
            if (obj instanceof Activity && !((Activity) obj).isFinishing()) {
                // 确认Activity是否不可用
                baseHandleMessage(msg,t);

            } else if (obj instanceof Fragment && !((Fragment) obj).isRemoving()) {
                //确认判断Fragment不可用
                baseHandleMessage(msg,t);
            }

        } else {
            // 没有实例不进行操作
            Log.i(TAG, "handleMessage: 没有实例不进行操作");
        }
    }

    /**
     * 抽象方法用户实现,用来处理具体的业务逻辑
     *
     * @param msg
     */
    public abstract void baseHandleMessage(Message msg,T obj);


}
